Imports System.Windows.Controls
Imports System.Windows.Input
Imports System.Windows


Public Class DashboardZoneProperty
    Inherits UIObject
    Implements IComparable(Of DashboardZoneProperty)


    Private _Commands As ObjectModel.ObservableCollection(Of DashboardZoneCommand)
    Private _Properties As ObjectModel.ObservableCollection(Of DashboardZoneProperty)
    Private _Prop As ComponentModel.PropertyDescriptor
    Private _Owner As DashboardZone
    Private _Type As Type
    Private _Name As String
    Private _Value As Object
    Private _Target As Object
    Private _EditCommand As ICommand = New DelegateCommand(AddressOf EditCommandExecute)

    Friend Shared _OptionsWindowOpen As Boolean
    Friend Shared _OtpionsModifiedProperties As Dictionary(Of DashboardZoneProperty, Object)
    Friend Shared _OtpionsModifiedPropertiesOriginalValues As SortedList(Of DashboardZoneProperty, Object)
    Friend Shared _OtpionsModifiedPropertiesModifiedValues As SortedList(Of DashboardZoneProperty, Object)

    Sub New()

    End Sub
    Sub New(ByVal owner As DashboardZone, ByVal propname As String)
        Me._Owner = owner
        Me._Prop = ComponentModel.TypeDescriptor.GetProperties(owner.Visual)(propname)
        Me._Include = True
    End Sub
    Sub New(ByVal owner As DashboardZone, ByVal target As Object, ByVal propname As String, ByVal propgroup As String)
        Me._Owner = owner
        Me._Prop = ComponentModel.TypeDescriptor.GetProperties(target)(propname)
        Me._Group = propgroup
        Me._Target = target
        If target.GetType() Is GetType(StyleObject) Then
            Me._Include = False
        Else
            Me._Include = True
        End If
    End Sub
    Sub New(ByVal owner As DashboardZone, ByVal target As Object, ByVal propname As String, ByVal propgroup As String, ByVal displayname As String)
        Me._Owner = owner
        Me._Prop = ComponentModel.TypeDescriptor.GetProperties(target)(propname)
        Me._Group = propgroup
        Me._Target = target
        Me._DisplayName = displayname
        If target.GetType() Is GetType(StyleObject) Then
            Me._Include = False
        Else
            Me._Include = True
        End If
    End Sub
    Sub New(ByVal owner As DashboardZone, ByVal propname As String, ByVal type As Type)
        Me._Owner = owner
        Me._Type = type
        Me._Name = propname
        Me._Include = True
    End Sub

    Public ReadOnly Property PropertyType As Type
        Get
            If _Prop Is Nothing Then Return _Type
            Return _Prop.PropertyType
        End Get
    End Property

    Public ReadOnly Property Name As String
        Get
            If _Prop Is Nothing Then Return _Name
            Return _Prop.Name
        End Get
    End Property

    Private _DisplayName As String
    Public Property DisplayName As String
        Get
            If String.IsNullOrEmpty(_DisplayName) Then Return Name
            Return _DisplayName
        End Get
        Set(ByVal value As String)
            _DisplayName = value
            OnPropertyChanged("DisplayName")
        End Set
    End Property


    Public Property Value As Object
        Get
            If _Prop Is Nothing Then Return Me._Value
            If Me._Target IsNot Nothing Then Return Me._Prop.GetValue(Me._Target)
            Return Me._Prop.GetValue(Me._Owner.Visual)
        End Get
        Set(ByVal value As Object)
            ProcessUndoRedoOriginalValue()
            If _Prop Is Nothing Then
                Me._Value = value
                Me._Owner.OnValueChanged(Me)
                OnPropertyChanged("Value")
                Return
            End If
            Dim temptarget As Object = If(Me._Target IsNot Nothing, Me._Target, Me._Owner.Visual)
            If value IsNot Nothing Then
                If value.GetType() Is GetType(String) _
                    And Me._Prop.PropertyType IsNot GetType(String) Then


                    Me._Prop.SetValue(temptarget, Me._Prop.Converter.ConvertFromString(value))
                    OnPropertyChanged("Value")

                ElseIf value.GetType() IsNot GetType(String) _
                         And Me._Prop.PropertyType Is GetType(String) Then

                    Me._Prop.SetValue(temptarget, value.ToString())
                    OnPropertyChanged("Value")
                Else
                    Me._Prop.SetValue(temptarget, value)
                    OnPropertyChanged("Value")
                End If
            Else
                Me._Prop.SetValue(temptarget, value)
                OnPropertyChanged("Value")
            End If
            ProcessUndoRedoModifiedValue()
        End Set
    End Property

    Public ReadOnly Property PossibleValues As IEnumerable
        Get
            If Me._Prop.PropertyType Is GetType(Boolean) Then
                Return New Boolean() {True, False}
            End If
            If Me._Prop.PropertyType.IsEnum Then
                Return [Enum].GetValues(Me._Prop.PropertyType)
            End If
            If Me._Prop.PropertyType Is GetType(Windows.Media.Brush) Then
                Return StandardBrushes.Items
            End If
            If Me._Prop.PropertyType Is GetType(Windows.Media.FontFamily) Then
                Return StantardFonts.Families
            End If
            If Me._Prop.PropertyType Is GetType(Windows.FontWeight) Then
                Return StantardFonts.Weights
            End If
            If Me._Prop.PropertyType Is GetType(Windows.FontStyle) Then
                Return StantardFonts.Styles
            End If
            If Me._Prop.PropertyType Is GetType(Windows.Media.DashStyles) Then
                Return StantardFonts.LineStyles
            End If
            Return Nothing
        End Get
    End Property

    Public Overridable ReadOnly Property Commands As ObjectModel.ObservableCollection(Of DashboardZoneCommand)
        Get
            Return _Commands
        End Get
    End Property

    Public Overridable ReadOnly Property Properties As ObjectModel.ObservableCollection(Of DashboardZoneProperty)
        Get
            Return _Properties
        End Get
    End Property

    Private _DataBinding As ViewModelDashboardDataBinding
    Public Property DataBinding As ViewModelDashboardDataBinding
        Get
            Return _DataBinding
        End Get
        Set(ByVal value As ViewModelDashboardDataBinding)
            _DataBinding = value
            OnPropertyChanged("DataBinding")
            Me._Owner.OnDataBindingChanged(Me)
        End Set
    End Property

    Private _Group As String
    Public Property Group As String
        Get
            Return _Group
        End Get
        Set(value As String)
            _Group = value
        End Set
    End Property

    Public Property EnableDimensionOnBinding As Boolean = False

    Public Property EditorTemplate As String

    Public ReadOnly Property EditCommand As ICommand
        Get
            Return _EditCommand
        End Get
    End Property

    Private Sub EditCommandExecute()
        If Me.Value Is Nothing Then
            Me.Value = Activator.CreateInstance(Me.PropertyType)
        End If
        If _Properties Is Nothing And Me.PropertyType IsNot GetType(StyleObject) Then
            Dim q = From p As ComponentModel.PropertyDescriptor In ComponentModel.TypeDescriptor.GetProperties(Me.PropertyType)
                    Where Not p.IsReadOnly
                    Select New DashboardZoneProperty(Me._Owner, Me.Value, p.Name, p.Category) _
                            With {.EditorTemplate = _
                                    If(p.Name.ToLower().Contains("Format") _
                                       And p.PropertyType Is GetType(String), "StringFormatCellEditingTemplate", "")}

            _Properties = New ObjectModel.ObservableCollection(Of DashboardZoneProperty)(q.AsEnumerable())
        End If
        Dim propgrid = New ViewDashboardPropertyGrid()
        propgrid.SetDashboardZoneProperty(Me)

        ModuleDashboarding._uiservice.ShowMessage(propgrid, Width:=600, Height:=600)

        If Me.PropertyType Is GetType(StyleObject) Then
            Me._Owner.OnValueChanged(Me)
        End If
    End Sub

    Private Sub ProcessUndoRedoOriginalValue()
        If _OptionsWindowOpen Then
            If Not _OtpionsModifiedPropertiesOriginalValues.ContainsKey(Me) Then
                _OtpionsModifiedPropertiesOriginalValues.Add(Me, Me.Value)
            End If
        End If

    End Sub
    Private Sub ProcessUndoRedoModifiedValue()
        If _OptionsWindowOpen Then
            If Not _OtpionsModifiedPropertiesModifiedValues.ContainsKey(Me) Then
                _OtpionsModifiedPropertiesModifiedValues.Add(Me, Me.Value)
            Else
                _OtpionsModifiedPropertiesModifiedValues(Me) = Me.Value
            End If
        End If
    End Sub

    Private _Include As Boolean = False
    Public Property Include As Boolean
        Get
            Return _Include
        End Get
        Set(ByVal value As Boolean)
            _Include = value
            OnPropertyChanged("Include")
        End Set
    End Property

    Private Function CompareTo(other As DashboardZoneProperty) As Integer Implements IComparable(Of DashboardZoneProperty).CompareTo
        If other Is Me Then Return 0
        Return If(other.GetHashCode() > Me.GetHashCode(), -1, 1)
    End Function
End Class

